﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace SetSailCommon
{
    /// <summary>
    /// Json的相关操作类
    /// </summary>
    public static class Json
    {
        public static T Read<T>(string jsonString)
        {
            T persons = JsonConvert.DeserializeObject<T>(jsonString);
            return persons;
        }

        public static string Write(object obj)
        {
            return JsonConvert.SerializeObject(obj).Replace("null", "\"\"");
        }

        public static T ToObject<T>(this string jsonString)
        {
            var obj = JsonConvert.DeserializeObject<T>(jsonString);
            return obj;
        }

        public static string ToJson(this object obj)
        {
            IsoDateTimeConverter dateFormat = new IsoDateTimeConverter();
            dateFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";//设置事件的格式
            return JsonConvert.SerializeObject(obj, dateFormat).Trim('"').Replace("\\", "").Replace("null", "\"\"");
        }

        public static string JsonTostring(IEnumerable array)
        {
            JsonSerializer serializer = new JsonSerializer();
            StringWriter sw = new StringWriter();
            serializer.Serialize(new JsonTextWriter(sw), array);
            return sw.GetStringBuilder().ToString();
        }

        public static string JsonTostring(object array)
        {
            JsonSerializer serializer = new JsonSerializer();
            StringWriter sw = new StringWriter();
            serializer.Serialize(new JsonTextWriter(sw), array);
            return sw.GetStringBuilder().ToString();
        }

        /// <summary>
        /// 处理特殊字符参数
        /// </summary>
        /// <param name="sqlPara">传入参数</param>
        /// <returns>特殊处理后的参数</returns>
        public static string CovertToSqlChar(string sqlPara)
        {
            if (sqlPara == null)
                return null;
            sqlPara = sqlPara.Replace("'", "''");
            //sqlPara = sqlPara.Replace("[", "'||chr(91)||'");
            //sqlPara = sqlPara.Replace("_", "'||chr(95)||'");
            //sqlPara = sqlPara.Replace("%", "[%]");
            sqlPara = sqlPara.Replace("%", "'||chr(37)||'");
            sqlPara = sqlPara.Replace("\"", "'||chr(34)||'");
            sqlPara = sqlPara.Replace("&", "'||chr(38)||'");
            sqlPara = sqlPara.Replace("<", "'||chr(60)||'");
            sqlPara = sqlPara.Replace(">", "'||chr(62)||'");
            sqlPara = sqlPara.Replace("delete", "");
            sqlPara = sqlPara.Replace("update", "");
            sqlPara = sqlPara.Replace("insert", "");
            //sqlPara = sqlPara.Replace("(", "/(");
            //sqlPara = sqlPara.Replace(")", "/)");
            //去除执行存储过程的命令关键字
            sqlPara = sqlPara.Replace("Exec", "");
            sqlPara = sqlPara.Replace("Execute", "");
            //去除系统存储过程或扩展存储过程关键字
            sqlPara = sqlPara.Replace("xp_", "x p_");
            sqlPara = sqlPara.Replace("sp_", "s p_");
            //防止16进制注入
            sqlPara = sqlPara.Replace("0x", "0 x");
            return sqlPara;
        }
        /// <summary>
        /// 判断是否含有非法字符
        /// </summary>
        /// <param name="sqlPara"></param>
        /// <returns></returns>
        public static bool HasInvalidChar(string sqlPara)
        {
            Regex reg = new Regex(@"['\\[ \\] \\^ \\_*()$% ~!@#$…&%￥<>;]");
            return reg.IsMatch(sqlPara);
        }
        /// <summary>
        /// 处理对象属性中特殊字符参数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="inputModel"></param>
        /// <returns></returns>
        public static T CovertToSqlCharByObject<T>(T obj)
        {
            if (obj != null)
            {
                Type t = obj.GetType();
                var typeFields = t.GetFields();
                if (typeFields != null && typeFields.Length > 0)
                {
                    foreach (var pi in typeFields)
                    {
                        //当属性为字符串时
                        if (pi.FieldType == typeof(string))
                        {
                            object proValue = pi.GetValue(obj);
                            if (proValue != null && !string.IsNullOrEmpty(proValue.ToString()))
                            {
                                //过滤字符串
                                pi.SetValue(obj, CovertToSqlChar(proValue.ToString()));
                            }
                        }
                        //else if (pi.FieldType.IsGenericType || pi.FieldType.IsArray || pi.FieldType.IsClass)
                        //{//当该属性为List泛型时，或者为引用类型，数组时
                        //    FieldInfo[] paras = pi.FieldType.GetFields();
                        //    if (paras != null && paras.Count() > 0)
                        //    {
                        //        int i = 0;
                        //        while (i < paras.Count())
                        //        {
                        //            FieldInfo tempItem = paras[i];
                        //            tempItem.SetValue(obj, CovertToSqlCharByObject(tempItem));
                        //            i++;
                        //        }
                        //    }
                        //}
                    }
                }
                var typePros = t.GetProperties();
                if (typePros != null && typePros.Length > 0)
                {
                    int proIndex = 0;
                    foreach (var pi in typePros)
                    {
                        //当属性为字符串时
                        if (pi.PropertyType == typeof(string))
                        {
                            object proValue = pi.GetValue(obj, null);
                            if (proValue != null && !string.IsNullOrEmpty(proValue.ToString()))
                            {
                                try
                                {
                                    //过滤字符串
                                    pi.SetValue(obj, CovertToSqlChar(proValue.ToString()), null);
                                }
                                catch (Exception ex)
                                {
                                    int i = 0;
                                }
                            }
                        }
                        //else if (pi.PropertyType.IsGenericParameter || pi.PropertyType.IsArray || pi.PropertyType.IsClass)
                        //{//当该属性为List泛型时，或者为引用类型，数组时
                        //    //死循环
                        //    //PropertyInfo[] paras = pi.PropertyType.GetProperties();
                        //    //if (paras != null && paras.Count() > 0)
                        //    //{
                        //    //    int i = 0;
                        //    //    while (i < paras.Count())
                        //    //    {
                        //    //        PropertyInfo tempItem = paras[i];
                        //    //        tempItem.SetValue(obj, CovertToSqlCharByObject(tempItem),null);
                        //    //        i++;
                        //    //    }
                        //    //}
                        //    object proValue = pi.GetValue(obj, null);
                        //    pi.SetValue(obj, CovertToSqlCharByObject(proValue), null);

                        //}
                        //proIndex++;
                    }
                }
            }
            return obj;
        }

        /// <summary>
        /// 深度拷贝
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="RealObject"></param>
        /// <returns></returns>
        public static T Clone<T>(T RealObject)
        {
            using (Stream objectStream = new MemoryStream())
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(objectStream, RealObject);
                objectStream.Seek(0, SeekOrigin.Begin);
                return (T)formatter.Deserialize(objectStream);
            }
        }

        public static T DeepCopy<T>(T obj)
        {
            //如果是字符串或值类型则直接返回
            if (obj == null)
            {

            }
            if (obj is string || obj.GetType().IsValueType) return obj;

            object retval = Activator.CreateInstance(obj.GetType());
            FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
            foreach (FieldInfo field in fields)
            {
                if (field.GetValue(obj) == null)
                { continue; }
                try { field.SetValue(retval, DeepCopy(field.GetValue(obj))); }
                catch { }
            }
            return (T)retval;
        }

        /// <summary>
        /// 将json数据转换为Dictionary,仅对一行数据操作
        /// </summary>
        /// <param name="strJson"></param>
        /// <param name="returnStr">json中要解析的对象</param>
        /// <returns></returns>
        public static Dictionary<string, object> JsonToDictionary(string strJson, string returnStr)
        {
            Dictionary<string, object> dic = new Dictionary<string, object>();
            try
            {
                //引用System.Web.Extensions
                JavaScriptSerializer json = new JavaScriptSerializer();
                Dictionary<string, object> list = json.DeserializeObject(strJson) as Dictionary<string, object>;
                if (list.Count > 0)
                {
                    dic = (((object[])list[returnStr])[0]) as Dictionary<string, object>;
                }
            }
            catch
            {
                return dic;
            }
            return dic;
        }

        /// <summary>
        /// 将对象转换成json
        /// </summary>
        /// <param name="obj">json数据</param>
        /// <param name="type">需要转换的对象</param>
        /// <returns></returns>
        public static string ObjectToJson(object obj)
        {
            JavaScriptSerializer json = new JavaScriptSerializer();
            return json.Serialize(obj.ToString());
        }

        
    }
}
